package cn.xyfmzmy;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 自定义线程池
 */
// 1.线程什么时候创建
// 2.线程的runnable是什么？是我们提交的command吗？
public class MyThreadPool {

    private final int corePoolSize;     // 核心线程数
    private final int maxSize;                // 最大线程数
    private final int timeout;                // 阻塞队列等待超时时间
    private final TimeUnit timeUnit;           // 阻塞队列等待超时时间单位
    public final BlockingQueue<Runnable> blockingQueue;            // 阻塞队列
    private final RejectHandle rejectHandle;                        // 拒绝策略

    public MyThreadPool(int corePoolSize,int maxSize,int timeout,TimeUnit timeUnit,
                        BlockingQueue<Runnable> blockingQueue,RejectHandle rejectHandle) {
        this.corePoolSize = corePoolSize;
        this.maxSize = maxSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.blockingQueue = blockingQueue;
        this.rejectHandle = rejectHandle;
    }


    // 核心线程集合
    List<Thread> coreList = new ArrayList<>();

    // 辅助线程集合
    List<Thread> supportList = new ArrayList<>();

    // 线程池执行任务
    synchronized void execute(Runnable command){
        // 核心线程数 < 最大核心线程数，创建新的线程执行任务
        if(coreList.size() < corePoolSize){
            CoreThread coreThread = new CoreThread();
            coreList.add(coreThread);
            coreThread.start();
        }
        // 添加任务成功直接结束，添加失败(阻塞队列满了)可以创建辅助线程(加快对任务的处理)
        if(blockingQueue.offer(command)){
            return;
        }
        // 核心线程数 + 辅助线程数 < 最大线程数，创建辅助线程执行任务
        if (coreList.size() + supportList.size() < maxSize) {
            SupportThread supportThread = new SupportThread();
            supportList.add(supportThread);
            supportThread.start();
        }
        if (!blockingQueue.offer(command)) {
            // 拒绝策略,阻塞队列满的时候执行
            rejectHandle.reject( command,this);
        }
    }

    // 关闭线程池
    void shutdown(){
        for(Thread thread:coreList){
            thread.stop();
        }
        for(Thread thread:supportList){
            thread.stop();
        }
    }

    // 自定义核心线程
    class CoreThread extends Thread {
        @Override
        public void run() {
            while(true){
                try {
                    // 阻塞方法，避免浪费cpu资源
                    Runnable command = blockingQueue.take();
                    command.run();
                }catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    // 自定义辅助线程
    class SupportThread extends Thread {
        @Override
        public void run() {
            while(true){
                try {
                    // 如果在一段时间内没有从阻塞队列中获取任务，认为不忙碌，关闭阻塞线程
                    Runnable command = blockingQueue.poll(timeout,timeUnit);
                    if(command == null){
                        break;
                    }
                    command.run();
                }catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println(Thread.currentThread().getName() + "线程结束了!");
        }
    }

}
